package com.adley.oauth.server.web;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.adley.oauth.server.mapper.ClientDetailsMapper;

@Controller
public class MainController {
    @Resource(name="tokenStore")
    private TokenStore tokenStore;
    @Autowired
    private ClientDetailsMapper clientDetailsMapper;

    @RequestMapping("/")
    public String root() {return "redirect:/index";}

    @RequestMapping("/index")
    public String index() {return "index";}

    @RequestMapping("/user/index")
    public String userIndex() {return "user/index";}

    @RequestMapping("/toauth/clients")
    public ModelAndView clients(ModelAndView modelAndView) {
        modelAndView.setViewName("oauth/client_list");
        modelAndView.addObject("clientIds",clientDetailsMapper.findAllIds());
        return modelAndView;
    }

    @GetMapping(path = "/toauth/tokens", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody ResponseEntity<List<String>> tokens(String clientId) {
        return new ResponseEntity(tokenStore.findTokensByClientId(clientId).stream().map(OAuth2AccessToken::getValue).collect(Collectors.toList()),HttpStatus.OK);
    }
    
    @PutMapping(path = "/toauth/revoketoken", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody ResponseEntity<String> revoketoken(@RequestParam String clientId, @RequestParam String tokenId) {
        Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientId(clientId);
        if (CollectionUtils.isEmpty(tokens)) {
            return new ResponseEntity<>("token不存在",HttpStatus.OK);
        }
        Optional<OAuth2AccessToken> token = tokens.stream().filter(o->o.getValue().equalsIgnoreCase(tokenId)).findFirst();
        if (token.isPresent()) {
            tokenStore.removeAccessToken(token.get());
            return new ResponseEntity<>("token回收成功",HttpStatus.OK);
        } else {
            return new ResponseEntity<>("token不存在",HttpStatus.OK);
        }
    }

    @RequestMapping("/login")
    public String login() {return "login";}

    @RequestMapping("/login-error")
    public String loginError(Model model, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        String errorMessage = null;
        if (session != null) {
            errorMessage = ((Throwable)session.getAttribute("SPRING_SECURITY_LAST_EXCEPTION")).getMessage();
        }
        model.addAttribute("errorMessage",errorMessage);
        model.addAttribute("loginError",true);
        return "login";
    }
}
